//----------------------------------------------------------------
//module name : yhz_common_register
//engineer : yhz
//date : 2021.07.27
//----------------------------------------------------------------
`include "yhz_defines.v"
module yhz_common_register (
    input  wire        i_clk                 ,
    input  wire        i_rst                 ,
    //rd
    input  wire        i_w_rd_en             ,
    input  wire [4:0]  i_w_rd_addr           ,
    input  wire [63:0] i_w_rd_data           ,
    //rs
    input  wire        i_r_rs1_en            ,
    input  wire        i_r_rs2_en            ,
    input  wire [4:0]  i_r_rs1_addr          ,
    input  wire [4:0]  i_r_rs2_addr          ,
    output wire [63:0] o_r_rs1_data          ,
    output wire [63:0] o_r_rs2_data          ,
    //difftest
    output wire [63:0] o_reg_difftest [31:0]  
);
//----------------------------------------------------------------
//register & wire
//----------------------------------------------------------------
    reg [63:0] common_register [31:0] ;
    reg [63:0] rs1_data               ;
    reg [63:0] rs2_data               ;
//----------------------------------------------------------------
//logic
//----------------------------------------------------------------
    //common_register
    always @(posedge i_clk) begin
        if(i_rst) begin
            common_register[0]  <= 64'd0 ;
            common_register[1]  <= 64'd0 ;
            common_register[2]  <= 64'd0 ;
            common_register[3]  <= 64'd0 ;
            common_register[4]  <= 64'd0 ;
            common_register[5]  <= 64'd0 ;
            common_register[6]  <= 64'd0 ;
            common_register[7]  <= 64'd0 ;
            common_register[8]  <= 64'd0 ;
            common_register[9]  <= 64'd0 ;
            common_register[10] <= 64'd0 ;
            common_register[11] <= 64'd0 ;
            common_register[12] <= 64'd0 ;
            common_register[13] <= 64'd0 ;
            common_register[14] <= 64'd0 ;
            common_register[15] <= 64'd0 ;
            common_register[16] <= 64'd0 ;
            common_register[17] <= 64'd0 ;
            common_register[18] <= 64'd0 ;
            common_register[19] <= 64'd0 ;
            common_register[20] <= 64'd0 ;
            common_register[21] <= 64'd0 ;
            common_register[22] <= 64'd0 ;
            common_register[23] <= 64'd0 ;
            common_register[24] <= 64'd0 ;
            common_register[25] <= 64'd0 ;
            common_register[26] <= 64'd0 ;
            common_register[27] <= 64'd0 ;
            common_register[28] <= 64'd0 ;
            common_register[29] <= 64'd0 ;
            common_register[30] <= 64'd0 ;
            common_register[31] <= 64'd0 ;
        end
        else if(i_w_rd_en && (i_w_rd_addr != 5'd0)) begin
            common_register[i_w_rd_addr] <= i_w_rd_data ;
        end
        else begin
            common_register[0]  <= common_register[0]  ;
            common_register[1]  <= common_register[1]  ;
            common_register[2]  <= common_register[2]  ;
            common_register[3]  <= common_register[3]  ;
            common_register[4]  <= common_register[4]  ;
            common_register[5]  <= common_register[5]  ;
            common_register[6]  <= common_register[6]  ;
            common_register[7]  <= common_register[7]  ;
            common_register[8]  <= common_register[8]  ;
            common_register[9]  <= common_register[9]  ;
            common_register[10] <= common_register[10] ;
            common_register[11] <= common_register[11] ;
            common_register[12] <= common_register[12] ;
            common_register[13] <= common_register[13] ;
            common_register[14] <= common_register[14] ;
            common_register[15] <= common_register[15] ;
            common_register[16] <= common_register[16] ;
            common_register[17] <= common_register[17] ;
            common_register[18] <= common_register[18] ;
            common_register[19] <= common_register[19] ;
            common_register[20] <= common_register[20] ;
            common_register[21] <= common_register[21] ;
            common_register[22] <= common_register[22] ;
            common_register[23] <= common_register[23] ;
            common_register[24] <= common_register[24] ;
            common_register[25] <= common_register[25] ;
            common_register[26] <= common_register[26] ;
            common_register[27] <= common_register[27] ;
            common_register[28] <= common_register[28] ;
            common_register[29] <= common_register[29] ;
            common_register[30] <= common_register[30] ;
            common_register[31] <= common_register[31] ;
        end
    end
    //rs1_data
    always @(*) begin
        if(i_rst) begin
            rs1_data = 64'd0 ;
        end
        else if(i_r_rs1_en) begin
            rs1_data = common_register[i_r_rs1_addr] ;
        end
        else begin
            rs1_data = 64'd0 ;
        end
    end
    //rs2_data
    always @(*) begin
        if(i_rst) begin
            rs2_data = 64'd0 ;
        end
        else if(i_r_rs2_en) begin
            rs2_data = common_register[i_r_rs2_addr] ;
        end
        else begin
            rs2_data = 64'd0 ;
        end
    end
//----------------------------------------------------------------
//output
//----------------------------------------------------------------
    assign o_r_rs1_data = rs1_data ;
    assign o_r_rs2_data = rs2_data ;
//----------------------------------------------------------------
//difftest
//----------------------------------------------------------------
    genvar i;
	generate
		for (i = 0; i < 32; i = i + 1) begin
			assign o_reg_difftest[i] = (i_w_rd_en & i_w_rd_addr == i & i != 0) ? 
                                        i_w_rd_data : common_register[i] ;
		end
	endgenerate
//----------------------------------------------------------------
endmodule
//----------------------------------------------------------------
